#include "PreCompile.hpp"
#include "Module.hpp"
#include "LibBuildNGInit.hpp"
#include "Project.hpp"
#include "ErrorListener.hpp"

namespace BuildNG
{  
  Module::Module()
  {
    assert_libbuildng_initialized();
  }

  bool Module::build(const Glib::ustring &output_root_dir,
    Glib::RefPtr<ErrorListener> error_listener)
  {
    Glib::ustring root_dir;
    if(project)
      root_dir = project->get_root_dir();
    else
      root_dir = module_dir;

    BuildContext context(root_dir,Glib::build_filename(root_dir,".build"));
    context.begin();

    bool success = true;
    
    context.push_module(this_ptr<Module>());
    error_listener->begin_build_module(this_ptr<Module>());

    bool cur_success = build(context,error_listener);
    if(!cur_success)
      success = false;

    error_listener->end_build_module(this_ptr<Module>());
    context.pop_module();

    context.end();

    return success;
  }

  /////////////
  // Module types registry
  static std::map<Glib::ustring,ModuleTypeInfo> module_type_infos;
  typedef std::map<Glib::ustring,ModuleTypeInfo>::iterator ModuleTypesInfosIt;
  typedef std::map<Glib::ustring,ModuleTypeInfo>::const_iterator ConstModuleTypesInfosIt;
  
  void register_module_type(const Glib::ustring &name,const ModuleTypeInfo &module_type_info)
  {
    assert(module_type_infos.find(name) == module_type_infos.end());
    
    module_type_infos[name] = module_type_info;
  }
  
  const ModuleTypeInfo* get_module_type_info(const Glib::ustring &type_name)
  {
    ConstModuleTypesInfosIt it = module_type_infos.find(type_name);
    if(it != module_type_infos.end())
      return &it->second;
    else
      return NULL;
  }
}

